package com.stone.zeus.component.grpc.config;

import com.zb.zeus.common.core.exception.BaseException;
import com.zb.zeus.common.core.web.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;

/**
 * 全局异常拦截处理类,处理系统出现的各种异常，并统一封装返回提示
 *
 * @author 李文龙
 */
@RestControllerAdvice
public class GlobalDefaultExceptionHandler {

    private final static Logger logger = LoggerFactory.getLogger(GlobalDefaultExceptionHandler.class);

    @Value("${spring.application.name:NA}")
    private String appName;

    @Value("${spring.profiles.active:NA}")
    private String env;

    @Autowired(required = false)
    private ServiceInstance instance;

    //@ResponseBody
    //@ExceptionHandler(ExcelAnalysisException.class)
    //public BaseResp handleExcelAnalysisException(ExcelAnalysisException e) {
    //    LogUtils.send(env, HttpStatus.INTERNAL_SERVER_ERROR.toString(), instance, appName, e);
    //    BaseResp ret = BaseResp.build(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getCause().getMessage(), null);
    //    logger.error(e.getCause().getMessage(), e);
    //    return ret;
    //}

    @ResponseBody
    @ExceptionHandler({IllegalArgumentException.class})
    public AjaxResult badRequestException(IllegalArgumentException e) {
        AjaxResult ret = new AjaxResult(HttpStatus.BAD_REQUEST.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public AjaxResult handleError(MissingServletRequestParameterException e) {
        //LogUtils.send(env, HttpStatus.BAD_REQUEST.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.BAD_REQUEST.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public AjaxResult handleError(MethodArgumentTypeMismatchException e) {
        //LogUtils.send(env, HttpStatus.BAD_REQUEST.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.BAD_REQUEST.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public AjaxResult handleError(MethodArgumentNotValidException e) {
        //LogUtils.send(env, HttpStatus.BAD_REQUEST.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.BAD_REQUEST.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(BindException.class)
    public AjaxResult handleError(BindException e) {
        //LogUtils.send(env, HttpStatus.BAD_REQUEST.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.BAD_REQUEST.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(ConstraintViolationException.class)
    public AjaxResult handleError(ConstraintViolationException e) {
        //LogUtils.send(env, HttpStatus.BAD_REQUEST.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.BAD_REQUEST.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(NoHandlerFoundException.class)
    public AjaxResult handleError(NoHandlerFoundException e) {
        //LogUtils.send(env, HttpStatus.NOT_FOUND.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.NOT_FOUND.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public AjaxResult handleError(HttpMessageNotReadableException e) {
        //LogUtils.send(env, HttpStatus.INTERNAL_SERVER_ERROR.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public AjaxResult handleError(HttpRequestMethodNotSupportedException e) {
        //LogUtils.send(env, HttpStatus.METHOD_NOT_ALLOWED.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.METHOD_NOT_ALLOWED.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ResponseBody
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public AjaxResult handleError(HttpMediaTypeNotSupportedException e) {
        //LogUtils.send(env, HttpStatus.UNSUPPORTED_MEDIA_TYPE.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), e.getMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ExceptionHandler(value = BaseException.class)
    @ResponseBody
    public AjaxResult busiErrorHandler(HttpServletRequest req, BaseException e) {
        AjaxResult ret = new AjaxResult(HttpStatus.BAD_REQUEST.value(), e.getDefaultMessage(), null);
        logger.error(e.toString(), e);
        return ret;
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public AjaxResult defaultErrorHandler(HttpServletRequest req, Exception e) {
        //LogUtils.send(env, HttpStatus.INTERNAL_SERVER_ERROR.toString(), instance, appName, e);
        AjaxResult ret = new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误", null);
        logger.error(e.toString(), e);
        return ret;
    }

}
